/* =============================================================
 * carousel-.js v1.0.0
 * =============================================================
 * Original written by Ysy
 * =============================================================
 * Date 12/08/2019
 * ============================================================ */


(function (factory) {
    "use strict";
    if (typeof define === "function" && define.amd) {
        define(["jquery"], factory);
    } else {
        factory(jQuery);
    }
}(function ($) {

    let Carousel = function (element, options) {
        this.$main = $(element);
        this.$wrap = this.$main.find(".wrap");
        this.$items = this.$wrap.find("a");

        this.options = $.extend({}, $.fn.carousel.defaults, options);
        this.currentImage = this.options.curPage - 1;
        this.imageLength = this.$items.length;
        this.targetImage = 0;
        this.finish = true;
        this.model = this.options.playEffect[0] - 1;
        this.width = 0;
        this.height = 0;

        this.init();
        this.listen();
        this.play();
    }

    Carousel.prototype = {

        constructor: Carousel,

        play: function () {
            let self = this;

            if (!this.options.isAutoPlay) return;

            // clearInterval(this.playTime);

            this.playTime = setInterval(function () {
                self.toggleMove(self.options.playIndex);
            }, this.options.playInterval);
        },

        toggleMove: function (command) {
            if (!this.finish) return;
            this.finish = false;

            if ("previous" === command) {
                this.targetImage = this.currentImage - 1;
                if (this.currentImage === 0) this.targetImage = this.imageLength - 1;
            } else if ("next" === command) {
                this.targetImage = this.currentImage + 1;
                if (this.currentImage === this.imageLength - 1) this.targetImage = 0;
            }

            this.moveMode();
        },

        moveMode: function () {

            if (this.options.playEffect.length === 0) {
                this.model = this.random(0, 13);
            } else {
                if (this.model > this.options.playEffect[this.options.playEffect.length - 1]) {
                    this.model = this.options.playEffect[0];
                } else {
                    this.model += 1;
                }
            }

            switch (this.model) {
                case 0:
                    this.wholeSwitch(0);
                    break;
                case 1:
                    this.wholeSwitch(1);
                    break;
                case 2:
                    this.wholeSwitch(2);
                    break;
                case 3:
                    this.wholeSwitch(3);
                    break;
                case 4:
                    this.verticalSwitch(0);
                    break;
                case 5:
                    this.verticalSwitch(1);
                    break;
                case 6:
                    this.verticalSwitch(2);
                    break;
                case 7:
                    this.levelSwitch(0);
                    break;
                case 8:
                    this.levelSwitch(1);
                    break;
                case 9:
                    this.levelSwitch(2);
                    break;
                case 10:
                    this.opacitySwitch();
                    break;
                case 11:
                    this.shutterSwitch();
                    break;
                case 12:
                    this.diagonalShutterSwitch();
                    break;
                case 13:
                    this.gridShutterSwitch();
                    break;
                default:
                    this.opacitySwitch();
                    break;
            }
        },

        // 表格对角线百叶窗特效
        gridShutterSwitch: function () {
            let $current = this.$items.eq(this.currentImage),
                $target = this.$items.eq(this.targetImage),
                imageHtml = $current.html(),
                time = 1200;

            $target.find("img").css({zIndex: 9});
            $current.find("img").fadeOut();

            for (let i = 0; i < 20; i++) {
                let $createElem = $("<div></div>");

                // 设置滚动元素
                $createElem.html(imageHtml).css({
                    position: "absolute",
                    top: (this.height / 4) * Math.floor(i / 5),
                    left: (this.width / 5) * (i % 5),
                    zIndex: 10,
                    overflow: "hidden",
                    width: this.width / 5,
                    height: this.height / 4,
                });

                $current.append($createElem);

                $createElem.find("img").css(this.imgResizeStyle());

                let marginTop = -(this.height / 4) * Math.floor(i / 5) - (.5 * this.width * 1080 / 1920 - this.height / 8 * 3);
                let marginLeft = -(this.width / 5) * (i % 5) - this.width / 10;

                if (this.width / this.height < 1920 / 1080) {
                    marginTop = -(this.height / 4) * Math.floor(i / 5) - this.height / 8;
                    marginLeft = -(this.width / 5) * (i % 5) - (.5 * 1920 / 1080 * this.height - this.width / 10 * 4);
                }

                $createElem.find("img").css({
                    marginTop: marginTop,
                    marginLeft: marginLeft,
                });
            }

            $current.find("div").each((index, value) => {
                if (index % 2 === 0)
                    $(value).find("img").velocity({marginLeft: $(value).width()}, {duration: 500});
            });

            setTimeout(() => {
                $current.find("div").each((index, value) => {
                    if (index % 1 === 0)
                        $(value).find("img").velocity({marginLeft: $(value).width()}, {duration: 500});
                });
            }, 600);

            this.recovery($current, $target, imageHtml, time);
        },

        // 对角线百叶窗特效
        diagonalShutterSwitch: function () {
            let $current = this.$items.eq(this.currentImage),
                $target = this.$items.eq(this.targetImage),
                imageHtml = $current.html(),
                time = 1200;

            $target.find("img").css({zIndex: 9});
            $current.find("img").fadeOut();

            for (let i = 0; i < 24; i++) {
                let $createElem = $("<div></div>");

                // 设置滚动元素
                $createElem.html(imageHtml).css({
                    position: "absolute",
                    top: (this.height / 4) * Math.floor(i / 6),
                    left: (this.width / 6) * (i % 6),
                    zIndex: 10,
                    overflow: "hidden",
                    width: this.width / 6,
                    height: this.height / 4,
                });

                $current.append($createElem);

                $createElem.find("img").css(this.imgResizeStyle());

                let marginTop = -(this.height / 4) * Math.floor(i / 6) - (.5 * this.width * 1080 / 1920 - this.height / 8 * 3);
                let marginLeft = -(this.width / 6) * (i % 6) - this.width / 12;

                if (this.width / this.height < 1920 / 1080) {
                    marginTop = -(this.height / 4) * Math.floor(i / 6) - this.height / 8;
                    marginLeft = -(this.width / 6) * (i % 6) - (.5 * 1920 / 1080 * this.height - this.width / 12 * 5);
                }

                $createElem.find("img").css({
                    marginTop: marginTop,
                    marginLeft: marginLeft,
                });
            }

            this.recovery($current, $target, imageHtml, time);

            coordinate = this.getCoordinate($current.find("div"), 4, 6);

            this.setGrid(coordinate, 0, 0, function () {
                let left = parseInt(this.style.left);
                let top = parseInt(this.style.top);

                $(this).velocity({
                    left: left + 100,
                    top: top + 100,
                    opacity: 0
                });
            }, 100, +1, +1);
        },

        // 百叶窗特效
        shutterSwitch: function () {
            let self = this,
                $current = this.$items.eq(this.currentImage),
                $target = this.$items.eq(this.targetImage),
                imageHtml = $current.html(),
                speed = 0,
                time = 1200;

            $target.find("img").css({zIndex: 9});
            $current.find("img").fadeOut();

            for (let i = 0; i < 12; i++) {
                let $createElem = $("<div></div>");

                // 设置滚动元素
                $createElem.html(imageHtml).css({
                    position: "absolute",
                    top: 0,
                    left: this.width / 12 * i,
                    zIndex: 10,
                    overflow: "hidden",
                    width: this.width / 12,
                    height: this.height,
                    opacity: 1,
                });

                $current.append($createElem);

                $createElem.find("img").css(this.imgResizeStyle());
                $createElem.find("img").css({
                    marginLeft: -this.width / 12 * i - this.width / 24,
                });
            }

            $current.find("div").each((index, value) => {
                speed = index * 80;
                $(value).velocity({opacity: 0}, {duration: 320 + speed});
            });

            this.recovery($current, $target, imageHtml, time);
        },

        // 透明特效
        opacitySwitch: function () {
            let self = this,
                $createElem = $("<div></div>"),
                $current = this.$items.eq(this.currentImage),
                $target = this.$items.eq(this.targetImage),
                imageHtml = $current.html(),
                time = 1200;

            $target.find("img").css({zIndex: 9});
            $current.find("img").fadeOut();

            $createElem.html(imageHtml).css({
                position: "absolute",
                zIndex: 10,
                left: 0,
                top: 0,
                overflow: "hidden",
                width: this.width,
                height: this.height,
                opacity: 1
            });

            $createElem.find("img").css(this.imgResizeStyle());

            $current.append($createElem);

            // 图片特效
            $createElem.velocity({opacity: 0}, {duration: 1000});

            // 图片恢复处理
            this.recovery($current, $target, imageHtml, time);
        },

        // 横向切换特效
        levelSwitch: function (model) {
            let self = this,
                $current = this.$items.eq(this.currentImage),
                $target = this.$items.eq(this.targetImage),
                imageHtml = $current.html(),
                time = 1200,
                movingValue = 0,
                speed = 0;

            // 将要显示的图片置上
            $target.find("img").css({zIndex: 9});
            // 隐藏当前图片
            $current.find("img").fadeOut();

            for (let i = 0; i < 12; i++) {
                let $createElem = $("<div></div>");

                // 设置滚动元素
                $createElem.html(imageHtml).css({
                    position: "absolute",
                    top: this.height / 12 * i,
                    left: 0,
                    zIndex: 10,
                    overflow: "hidden",
                    width: this.width,
                    height: this.height / 12,
                });

                $current.append($createElem);

                $createElem.find("img").css(this.imgResizeStyle());
                $createElem.find("img").css({
                    marginTop: -this.height / 12 * i - (.5 * this.width * 1080 / 1920 - this.height / 24 * 11),
                });

                if (this.width / this.height < 1920 / 1080) {
                    $createElem.find("img").css({
                        marginTop: -this.height / 12 * i - this.height / 24,
                    });
                }
            }

            // 图片特效
            switch (model) {
                case 0:
                    $current.find("div").each((index, value) => {
                        movingValue = index % 2 === 0 ? self.width : -self.width;
                        $(value).velocity({left: movingValue}, {duration: 1000});
                    });
                    break;
                case 1:
                    $current.find("div").each((index, value) => {
                        speed = 80 * index;
                        $(value).velocity({left: $(value).width()}, {duration: 120 + speed});
                    });
                    break;
                case 2:
                    $current.find("div").each((index, value) => {
                        speed = 80 * index;
                        $(value).velocity({left: -$(value).width()}, {duration: 120 + speed});
                    });
            }

            // 图片恢复处理
            this.recovery($current, $target, imageHtml, time);
        },

        // 纵向切换特效
        verticalSwitch: function (model) {
            let self = this,
                $current = this.$items.eq(this.currentImage),
                $target = this.$items.eq(this.targetImage),
                imageHtml = $current.html(),
                time = 1200,
                movingValue = 0,
                speed = 0;

            // 将要显示的图片置上
            $target.find("img").css({zIndex: 9});
            // 隐藏当前图片
            $current.find("img").fadeOut();

            for (let i = 0; i < 12; i++) {
                let $createElem = $("<div></div>");

                // 设置滚动元素
                $createElem.html(imageHtml).css({
                    position: "absolute",
                    top: 0,
                    left: this.width / 12 * i,
                    zIndex: 10,
                    overflow: "hidden",
                    width: this.width / 12,
                    height: this.height,
                });

                $current.append($createElem);

                $createElem.find("img").css(this.imgResizeStyle());
                $createElem.find("img").css({
                    marginLeft: -this.width / 12 * i - this.width / 24,
                });
            }

            // 图片特效
            switch (model) {
                case 0:
                    $current.find("div").each((index, value) => {
                        movingValue = index % 2 === 0 ? self.height : -self.height;
                        $(value).velocity({top: movingValue}, {duration: 1000});
                    });
                    break;
                case 1:
                    $current.find("div").each((index, value) => {
                        speed = 80 * index;
                        $(value).velocity({top: $(value).height()}, {duration: 120 + speed});
                    });
                    break;
                case 2:
                    $current.find("div").each((index, value) => {
                        speed = 80 * index;
                        $(value).velocity({top: -$(value).height()}, {duration: 120 + speed});
                    });
            }

            // 图片恢复处理
            this.recovery($current, $target, imageHtml, time);
        },

        // 整图切换
        wholeSwitch: function (model) {
            let $current = this.$items.eq(this.currentImage),
                $target = this.$items.eq(this.targetImage),
                $createElem = $("<div></div>"),
                imageHtml = $current.html(),
                time = 1200,
                movingValue = 0;

            // 将要显示的图片置上
            $target.find("img").css({zIndex: 9});
            // 隐藏当前图片
            $current.find("img").fadeOut();

            // 设置滚动元素
            $createElem.html(imageHtml).css({
                position: "absolute",
                zIndex: 10,
                width: this.width,
                height: this.height,
            });
            $current.append($createElem);

            // 根据div和图片比例  设置移动幅度
            movingValue = this.height - .5 * this.width * 1080 / 1920;
            if (this.width / this.height < 1920 / 1080)
                movingValue = this.width - .5 * 1920 / 1080 * this.height;
            // 移动端
            if (this.width < 1024)
                movingValue = 0;


            // 图片特效
            switch (model) {
                case 0:
                    $createElem.velocity({left: this.width + movingValue}, {duration: 1000});
                    break;
                case 1:
                    $createElem.velocity({left: -this.width - movingValue}, {duration: 1000});
                    break;
                case 2:
                    $createElem.velocity({top: this.height + movingValue}, {duration: 1000});
                    break;
                case 3:
                    $createElem.velocity({top: -this.height - movingValue}, {duration: 1000});
                    break;
            }

            // 图片恢复处理
            this.recovery($current, $target, imageHtml, time);
        },

        // 图片自适应样式
        imgResizeStyle: function () {
            let style = {};

            style.width = this.width;
            style.height = "auto";
            style.margin = -.5 * this.width * 1080 / 1920 + "px 0 0 " + -.5 * this.width + "px";

            if (this.width / this.height < 1920 / 1080) {
                style.width = "auto";
                style.height = this.height;
                style.margin = -.5 * this.height + "px 0 0 " + -.5 * 1920 / 1080 * this.height + "px";
            }

            return style;
        },

        // 图片恢复处理
        recovery: function ($current, $target, imageHtml, time) {
            let self = this;
            this.currentImage++;

            setTimeout(() => {
                $target.find("img").css({zIndex: 10});
                $current.html(imageHtml);
                $current.find("img").css({zIndex: 1});
                self.finish = true;
                self.currentImage = self.targetImage;
            }, time);
        },

        // 设置表格特效
        setGrid: function (array, x, y, func, delay, speedX, speedY) {
            if (!array[y] || !array[y][x] || !func) return;

            func.call(array[y][x]);

            clearTimeout(array[y][x].timer);
            array[y][x].timer = setTimeout(() => {
                this.setGrid(array, x, y + speedY, func, delay, speedX, speedY);
                this.setGrid(array, x + speedX, y, func, delay, speedX, speedY);
            }, delay);
        },

        // 获取坐标
        getCoordinate: function (objects, rows, column) {
            let array = [];

            for (let i = 0; i < rows; i++) {
                let arrayTwo = [];

                for (let j = 0; j < column; j++) {
                    objects[i * column + j].xIndex = j;
                    objects[i * column + j].yIndex = i;

                    arrayTwo.push(objects[i * column + j]);
                }

                array.push(arrayTwo);
            }

            return array;
        },

        // 随机数
        random: function (min, max) {
            return Math.floor(Math.random() * (max + 1) - min);
        },

        // 初始化
        init: function () {
            this.resize();
        },

        // 事件监听
        listen: function () {
            let self = this;

            // 全屏下响应式调整
            if (this.options.isFullPage) {
                $(window).resize(function () {
                    self.resize();
                });
            }

        },

        // 自适应
        resize: function () {
            this.width = Object.is("100%", this.options.width) ? $(window).width() : this.options.width;
            this.height = Object.is("100%", this.options.height) ? $(window).height() : this.options.height;

            if (this.options.isFullPage) {
                this.width = $(window).width();
                this.height = $(window).height();
            }

            this.$main.width(this.width);
            this.$main.height(this.height);

            // 移动端
            if (this.width < 1024) {
                this.$main.find("img").width(this.width).css({
                    height: "auto",
                    margin: -.5 * this.height + "px 0 0 " + -.5 * this.width + "px",
                });
                return;
            }

            if (this.width / this.height < 1920 / 1080) {
                this.$main.find("img").height(this.height).css({
                    width: "auto",
                    margin: -.5 * this.height + "px 0 0 " + -.5 * 1920 / 1080 * this.height + "px",
                });
                return;
            }

            this.$main.find("img").width(this.width).css({
                height: "auto",
                margin: -.5 * this.width * 1080 / 1920 + "px 0 0 " + -.5 * this.width + "px",
            });
        }
    };

    $.fn.carousel = function (options) {
        this.each(() => {
            new Carousel(this, options);
        });
    };

    $.fn.carousel.Constructor = Carousel;

    $.fn.carousel.defaults = {
        width: 800,         // 容器宽度
        height: 400,        // 容器高度
        curPage: 1,         // 当前显示页
        isFullPage: true,   // 是否全屏展示
        isAutoPlay: true,   // 是否自动播放
        playInterval: 3000, // 自动播放时间
        isNavBtn: false,    // 是否显示导航按钮
        isBottomTip: false, // 是否需要底部提示
        playIndex: "next",  // 播放顺序  previous:倒序  next:正序
        playEffect: [],     // 轮播特效  0--13种  空为随机
    };

}));


